package com.iwhalecloud.bss.kite.cucc.order.bo.scene;

import com.iwhalecloud.bss.kite.client.api.shoppingcart.query.IQueryShoppingCartService;
import com.iwhalecloud.bss.kite.client.dto.order.OrderCommitRequestDTO;
import com.iwhalecloud.bss.kite.client.dto.shoppingcart.ShoppingCartGroupInstDTO;
import com.iwhalecloud.bss.kite.common.constant.KeyConsts;
import com.iwhalecloud.bss.kite.common.constant.SymbolConsts;
import com.iwhalecloud.bss.kite.common.constant.TableConsts;
import com.iwhalecloud.bss.kite.common.util.KiteDateUtils;
import com.iwhalecloud.bss.kite.common.util.KiteListUtils;
import com.iwhalecloud.bss.kite.common.util.KiteStringUtils;
import com.iwhalecloud.bss.kite.common.util.SeqUtils;
import com.iwhalecloud.bss.kite.dataservice.entity.KiteCustomerOrderRel;
import com.iwhalecloud.bss.kite.dataservice.entity.KiteShoppingCartGroupInstHis;
import com.iwhalecloud.bss.kite.dataservice.entity.KiteShoppingCartGroupInst;
import com.iwhalecloud.bss.kite.dataservice.mapper.shoppingcart.ShoppingCartGroupInstHisMapper;
import com.iwhalecloud.bss.kite.dataservice.mapper.shoppingcart.ShoppingCartGroupInstMapper;
import com.iwhalecloud.bss.kite.dataservice.util.SplictUtil;
import com.iwhalecloud.bss.kite.manager.api.IQuerySceneInstService;
import com.iwhalecloud.bss.kite.manager.inst.KiteAttr;
import com.iwhalecloud.bss.kite.manager.inst.KiteSceneInst;
import com.iwhalecloud.bss.kite.order.client.api.operate.IKiteCustomerOrderRelService;
import com.iwhalecloud.bss.kite.order.client.api.operate.IWithdrawOrderService;
import com.iwhalecloud.bss.kite.order.client.dto.OrderRequest;
import com.ztesoft.bss.base.staticdata.ServiceOfferConst;
import com.ztesoft.bss.common.util.SpringUtil;
import org.springframework.util.Assert;
import tk.mybatis.mapper.entity.Example;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * <Description> <br>
 * 场景实例合并业务对象
 *
 * @author xiao.xuzhang<br>
 * @version 1.0<br>
 * @taskId <br>
 * @CreateDate 2020年2月18日 <br>
 * @since R9.0<br>
 * @see com.iwhalecloud.bss.kite.cucc.order.bo.scene <br>
 */
public class SceneInstMergeBO {

    /**
     * 客户ID
     */
    private String custId;

    private String createStaff;

    private String updateStaff;

    /**
     * 场景实例集合
     */
    private List<KiteSceneInst> sceneInstList = new ArrayList<>();

    public SceneInstMergeBO(String custId) {
        this.setCustId(custId);
    }

    public String getCustId() {
        return custId;
    }

    public void setCustId(String custId) {
        this.custId = custId;
    }

    public List<KiteSceneInst> getSceneInstList() {
        if (Objects.isNull(sceneInstList)) {
            sceneInstList = new ArrayList<>();
        }
        return sceneInstList;
    }

    public void setSceneInstList(List<KiteSceneInst> sceneInstList) {
        this.sceneInstList = sceneInstList;
    }

    public String getCreateStaff() {
        return createStaff;
    }

    public void setCreateStaff(String createStaff) {
        this.createStaff = createStaff;
    }

    public String getUpdateStaff() {
        return updateStaff;
    }

    public void setUpdateStaff(String updateStaff) {
        this.updateStaff = updateStaff;
    }

    /**
     * Description: <br>
     * 判断是否包含场景实例
     *
     * @author xiao.xuzhang<br>
     * @taskId <br>
     * @param sceneInst
     * @return <br>
     */
    public boolean contains(KiteSceneInst sceneInst) {
        boolean flag = false;
        for (KiteSceneInst kiteSceneInst : this.getSceneInstList()) {
            if (KiteStringUtils.isEqual(sceneInst.getSceneInstId(), kiteSceneInst.getSceneInstId())) {
                flag = true;
                break;
            }
        }

        return flag;
    }

    /**
     * Description: <br>
     * 场景合并处理
     *
     * @author xiao.xuzhang<br>
     * @taskId <br>
     * @return <br>
     */
    public OrderRequest merge(OrderCommitRequestDTO request) {

        // 获取业务范围较大作为主场景实例
        KiteSceneInst mainSceneInst = this.getMainSceneInst();

        // 处理客户订单合并逻辑(预校验不处理)
        if (!request.getPreCheck()) {
            this.dealCustomerOrder(mainSceneInst);
        }

        // 初始化订单请求对象
        OrderRequest orderRequest = this.initOrderRequest(mainSceneInst, request);

        return orderRequest;
    }

    private OrderRequest initOrderRequest(KiteSceneInst mainSceneInst, OrderCommitRequestDTO request) {
        OrderRequest orderRequest = new OrderRequest();
        IQueryShoppingCartService queryShoppingCartService = SpringUtil.getBean(IQueryShoppingCartService.class);

        // 获取场景实例对象
        ShoppingCartGroupInstDTO groupInst = queryShoppingCartService
            .getGroupInstDTOByGroupId(mainSceneInst.getSceneInstId(), this.getCustId()).getResultObject();
        

        //以购物车数据库为准
        String acceptMode = Optional.ofNullable(groupInst).map(m -> m.getAcceptMode()).orElse(KeyConsts.ACCEPT_MODE_A);
        String askSource = Optional.ofNullable(groupInst).map(m -> m.getOrderSource()).orElse(KeyConsts.ORDER_SOURCE_EVT_C_0001_1401);
        
        // 初始化订单请求对象
        orderRequest.setCustId(mainSceneInst.getCustId());
        orderRequest.setSceneInstIds(this.getGroupIds());
        orderRequest.setCustOrderId(mainSceneInst.getCustOrderId());
        orderRequest.setMainSceneInstId(mainSceneInst.getSceneInstId());
        orderRequest.setAcceptMode(acceptMode);
        orderRequest.setAskSource(askSource);
        orderRequest.setNewCustId(mainSceneInst.getNewCustId());
        orderRequest.setServiceOfferId(mainSceneInst.getServiceOfferId());
        orderRequest.setOldCustOrderId(this.getOldCustOrderId(groupInst));
        orderRequest.setLanId(request.getLanId());
        orderRequest.setOrgId(request.getOrgId());
        orderRequest.setRegionId(request.getRegionId());
        orderRequest.setStaffId(request.getStaffId());
        orderRequest.setStaffCode(request.getStaffCode());
        orderRequest.setPostId(request.getPostId());

        //回填旧客户订单
        if (KiteStringUtils.equals(KeyConsts.SERVICE_WITHDRAW, orderRequest.getServiceOfferId())
            || KeyConsts.KITE_SCENE_INST_OPER_TYPE_1001.equals(mainSceneInst.getOperType())) {
            String oldSceneInstId = mainSceneInst.getOldSceneInstId();
            ShoppingCartGroupInstMapper shop = SpringUtil.getBean(ShoppingCartGroupInstMapper.class);
            Example ex = new Example(KiteShoppingCartGroupInst.class);
            ex.createCriteria().andEqualTo("groupId", oldSceneInstId);
            List<KiteShoppingCartGroupInst> shoppingCartGroupInsts = shop.selectByExample(ex);
            if (KiteListUtils.isNotEmpty(shoppingCartGroupInsts)) {
                orderRequest.setOldCustOrderId(shoppingCartGroupInsts.get(0).getCustOrderId());
            }
            else {
                // 部分竣工后，会清空购物车从购物车历史新回填custOrderId
                ShoppingCartGroupInstHisMapper shophis = SpringUtil.getBean(ShoppingCartGroupInstHisMapper.class);
                Example em = new Example(KiteShoppingCartGroupInstHis.class);
                em.createCriteria().andEqualTo("groupId", mainSceneInst.getOldSceneInstId());
                List<KiteShoppingCartGroupInstHis> shoppingCartGroupInst = shophis.selectByExample(em);
                Assert.notEmpty(shoppingCartGroupInst, "shoppingCartGroupInstHis is not empty!");
                orderRequest.setOldCustOrderId(shoppingCartGroupInst.get(0).getCustOrderId());
            }
        }

        // 撤单逻辑处理
        if (KiteStringUtils.equals(KeyConsts.SERVICE_WITHDRAW, orderRequest.getServiceOfferId())) {
            //获取撤单原因
            String undoReason = this.getUndoReason(mainSceneInst);

            List<String> askIds = this.getAskIds(mainSceneInst);
            IWithdrawOrderService withdrawOrderService = SpringUtil.getBean(IWithdrawOrderService.class);

            //组装撤单对象
            orderRequest = withdrawOrderService.createWithdrawOrderRequest(orderRequest, askIds,
                orderRequest.getOldCustOrderId(), undoReason);
        }
        return orderRequest;
    }

    private String getOldCustOrderId(ShoppingCartGroupInstDTO groupInst) {
        IQueryShoppingCartService queryShoppingCartService = SpringUtil.getBean(IQueryShoppingCartService.class);
        String custOrderId = "";
        String oldGroupId = Optional.ofNullable(groupInst).map(ShoppingCartGroupInstDTO::getOldGroupId).orElse("");
        if (!KiteStringUtils.isEmpty(oldGroupId)) {
            // 加载老客户订单
            // 获取老的购物车分组
            ShoppingCartGroupInstDTO oldGroupInst = queryShoppingCartService
                .getGroupInstDTOByGroupId(oldGroupId, this.getCustId()).getResultObject();
            if (Objects.isNull(oldGroupInst)) {
                oldGroupInst = queryShoppingCartService.getShoppingGroupInstHis(oldGroupId, this.getCustId())
                    .getResultObject();
            }
            custOrderId = Optional.ofNullable(oldGroupInst).map(ShoppingCartGroupInstDTO::getCustOrderId).orElse("");
        }
        return custOrderId;
    }

    /**
     * Description: <br>
     * 获取撤单业务原因
     *
     * @author xiao.xuzhang<br>
     * @taskId <br>
     * @param mainSceneInst
     * @return <br>
     */
    private String getUndoReason(KiteSceneInst mainSceneInst) {
        IQuerySceneInstService querySceneInstService = SpringUtil.getBean(IQuerySceneInstService.class);
        KiteAttr kiteAttr = querySceneInstService.getCommonAttr(mainSceneInst.getSceneInstId(), KeyConsts.REMARK);
        return Optional.ofNullable(kiteAttr).map(KiteAttr::getValue).orElse("");
    }

    private List<String> getAskIds(KiteSceneInst sceneInst) {
        List<String> askIds = new ArrayList<>();
        IQuerySceneInstService querySceneInstService = SpringUtil.getBean(IQuerySceneInstService.class);

        String strAskIds = querySceneInstService.getExtParameterValue(sceneInst.getSceneInstId(), "ask_id");
        if (KiteStringUtils.isNotEmpty(strAskIds)) {
            askIds = KiteListUtils.strToList(SymbolConsts.COMMA, strAskIds);
        }

        return askIds;
    }

    private List<String> getGroupIds() {
        return this.getSceneInstList().stream().map(p -> p.getSceneInstId()).collect(Collectors.toList());
    }

    private KiteSceneInst getMainSceneInst() {
        KiteSceneInst sceneInst = null;
        List<KiteSceneInst> sceneInstList = this.getSceneInstList();
        for (int i = 0; i < sceneInstList.size(); i++) {
            KiteSceneInst curInst = sceneInstList.get(i);
            if (Objects.isNull(sceneInst)) {
                sceneInst = curInst;
            }
            else {
                String aServOfferId = sceneInst.getServiceOfferId();
                String zServOfferId = curInst.getServiceOfferId();
                int num = this.compareServiceOfferRel(aServOfferId, zServOfferId);
                if (-1 == num) {
                    sceneInst = curInst;
                }
            }
        }

        if (Objects.isNull(sceneInst)) {
            sceneInst = sceneInstList.get(0);
        }
        return sceneInst;
    }

    /**
     * Description: <br>
     * 比较两个服务提供范围 <br>
     * 0： 范围相同 <br>
     * 1： 服务提供A >= 服务提供B <br>
     * -1： 服务提供B >= 服务提供A <br>
     * 2 : 互斥
     *
     * @taskId <br>
     * @param aServOfferId
     * @param zServOfferId
     * @return <br>
     */
    private int compareServiceOfferRel(String aServOfferId, String zServOfferId) {
        int num = 0;

        if (SplictUtil.isAllMutex(aServOfferId, zServOfferId)) {
            // 业务互斥不处理
            return 2;
        }

        if (KiteStringUtils.isEqual(aServOfferId, zServOfferId)) {
            return num;
        }

        if (SplictUtil.isEqualOrBigger(aServOfferId, zServOfferId) || KiteStringUtils.equalsAny(aServOfferId,
            ServiceOfferConst.service_offer_1, ServiceOfferConst.service_offer_2826)) {
            return 1;
        }
        else if (SplictUtil.isEqualOrBigger(zServOfferId, aServOfferId) || KiteStringUtils.equalsAny(zServOfferId,
            ServiceOfferConst.service_offer_1, ServiceOfferConst.service_offer_2826)) {
            return -1;
        }

        return num;
    }

    /**
     * Description: <br>
     * 客户订单处理
     *
     * @author xiao.xuzhang<br>
     * @taskId <br>
     * @param mainSceneInst <br>
     */
    public void dealCustomerOrder(KiteSceneInst mainSceneInst) {
        // 判断是否需要合并客户订单
        if (this.getSceneInstList().size() < 2) {
            return;
        }

        IKiteCustomerOrderRelService service = SpringUtil.getBean(IKiteCustomerOrderRelService.class);
        Date date = KiteDateUtils.getCurrentDate();
        for (KiteSceneInst kiteSceneInst : this.getSceneInstList()) {
            if (KiteStringUtils.equals(mainSceneInst.getSceneInstId(), kiteSceneInst.getSceneInstId())) {
                continue;
            }

            // 创建对象
            KiteCustomerOrderRel kiteCustomerOrderRel = new KiteCustomerOrderRel();
            kiteCustomerOrderRel.setCustomerOrderRelId(SeqUtils.getNextLong(TableConsts.KiteCustomerOrderRel));
            kiteCustomerOrderRel.setCustOrderId(mainSceneInst.getCustOrderId());
            kiteCustomerOrderRel.setRelatedCustOrderId(kiteSceneInst.getCustOrderId());
            kiteCustomerOrderRel.setCustId(mainSceneInst.getCustId());
            kiteCustomerOrderRel.setCreateStaff(this.getCreateStaff());
            kiteCustomerOrderRel.setUpdateStaff(this.getUpdateStaff());
            kiteCustomerOrderRel.setCreateDate(date);
            kiteCustomerOrderRel.setUpdateDate(date);
            kiteCustomerOrderRel.setStatusDate(date);
            kiteCustomerOrderRel.setStatusCd(KeyConsts.CUST_ORDER_TYPE_EVT_C_0012_1000);
            kiteCustomerOrderRel.setRemark("转单新流程客户订单合并");

            service.insertKiteCustomerOrderRel(kiteCustomerOrderRel);
        }

    }

}
